package example.runner2;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import service.network.NetworkCalculationService;
import materials.network.NetworkInterface;
import materials.result.NetworkResultInterface;

/**
 * Rennt durch das Feld und soll so viel essen wie möglich
 * 
 * @author Ramox
 *
 */
public class Runner
{
	private double _health; //Anzahl der gefutterten Essen
	private int _eaten; //Anzahl der wirklich gelaufenen schritte
	private NetworkInterface _netz;
	private int _steps;
	public final int LIVE = 800;
	
	
	
	public int getSteps(){
		return _steps;
	}
	
	public void raiseSteps(){
		_steps++;
	}
	/**
	 * Erzeugt einen Runner mit dem Netz netz
	 * 
	 * @param netz Netz des Runners
	 */
	public Runner(NetworkInterface netz)
	{
		_health = 5;
		_eaten = 0;
		_netz = netz;
	}

	/**
	 * gibt das netz zurück
	 * 
	 * @return netz des runners
	 */
	public NetworkInterface getNet()
	{
		return _netz;
	}

	/**
	 * gibt die Fitness des Runners aus
	 * 
	 * @return Fitness des Runners
	 */
	public double getFitness()
	{
		return _health;
	}

	/**
	 * Berechnet die Richtung in der der Runner seinen nächsten schritt machen will.
	 * 
	 * @param umgebung umgebung um den Runner (5x5)
	 * 
	 * @return Richtung in die der Runner gehen will
	 */
	public Direction getNextDirection(int[] umgebung)
	{
		NetworkCalculationService ncs = new NetworkCalculationService(_netz);
		double[] ndim = new double[25];

		
		//input für das netz
		for (int i = 0; i < 25; i++)
		{
			if (umgebung[i] == -3) //essen
			{
				ndim[i] = 1.0;
			}
			else if (umgebung[i] == -2) //essen
			{
				ndim[i] = 0.5;
			}
			else if (umgebung[i] == 0) //leer
			{
				ndim[i] = 0;
			}
			else if (umgebung[i]==-1)//wand und andere runner
			{
				ndim[i] = -0.5;
			}
			else
			{
				ndim[i] = -1;
			}
		}

		double[] nri = ncs.calculateInput(ndim);

		//berechnung der Ausgabe (51-58 sind die Neuronen in Layer 3)
		double max = nri[0];
		int maxId = 0;
		for (int i = 0; i < 8; i++)
		{
			if (nri[i] > max)
			{
				max = nri[i];
				maxId = i;
			}
		}
		
		//Richtung des Neuronen mit der größten Ausgabe ist die gewünschte
		return Direction.values()[maxId];
	}

	/**
	 * erhöht die Anzahl der Essen
	 */
	public void increaseHealth()
	{
		_health +=  1;
		increaseEaten();
	}

	/**
	 * erniedrigt die anzahl der Essen, wenn ein runner gegen die Wand läuft z.b.
	 */
	public void decreaseHealth()
	{
		_health -= 0.05;
	}

	/**
	 * erhöht die anzahl der schritte
	 */
	public void increaseEaten()
	{
		_eaten++;
	}
	
	public int getEaten(){
		return _eaten;
	}

	/**
	 * gibt die Anzahl der essen zurück
	 * 
	 * @return Anzahl der essen
	 */
	public double getHealth()
	{
		return _health;
	}

	public void reset() {
		_health = 0;		
	}

}
